#! /usr/bin/env python
# -*- coding:utf-8 -*-
import numpy as np
import configparser
import os
import datetime
import model_strategic as sa
import load_info as load
import utils_data as util
import logging
logging.basicConfig(level=logging.DEBUG, #日志级别为DEBUG
                    format="%(asctime)s %(pathname)s %(levelname)s %(lineno)d %(message)s", #日志格式设置
                    datefmt = '%Y-%m-%d  %H:%M:%S %a',    #日期格式设置
                    filename = os.getcwd()+'/common/logging.log')  #日志输入文件地址
"""
小时预测模型定义
结构：
    class predict_hour     #小时预测类
    def main #执行函数-获取能量、电量、工况小时预测并转换为list的
运行方式: 直接运行main（）
前置条件：model_hour.ini文件存在        
"""
class predict_hour:
    """
    预测能量、电量、工况小时曲线
    """
    def __init__(self,date):
        self.conf_path='/common/'   #model_hour.ini 根目录
        gp = load.Graph_load()
        self.graph_id = gp.put_databydate(date.strftime("%Y-%m-%d"))  #获取target对应日期的图谱ID
        ul = util.Device_util(self.graph_id)
        self.day_define = ul.day_define()  #日小时列表定义
        self.stgy_type = "1001"  #策略类型
    #获取各小时占日比率
    def get_hour_rate(self):
        """
        从model_hour.ini文件读取过渡季24小时用能占你
        :return:fea_list:list,各小时占比,shape = 1*24
        """
        config = configparser.ConfigParser(allow_no_value=True)
        cur_path = os.getcwd()
        feature_path = cur_path + self.conf_path+'/model_hour.ini'
        config.read(feature_path, "utf-8")
        feature = config['hour_rate']['hour_rate']
        fea_list = [float(i) for i in feature.split(",")]
        return fea_list
    #能量小时预测
    def energy_hour(self,strat_dict):
        """
        :param:strat_dict:dict,策略字典
        :return:hour_data：list,能量小时列表,shape =1*24
        """
        #获取策略字典和设备表
        ld = load.Device_load()
        hour_rate = self.get_hour_rate() #各小时占比比率

        if len(strat_dict)>0:
            device = ld.load_device(self.graph_id)
            #计算放能工况各小时和（17点到17点）
            data_list = []
            for key in strat_dict.keys():
                if device[device["device_id"] == key[1]]["type_id"].values[0] != 2:
                    data_list.append(np.array(strat_dict[key]))
            data_list = [sum(i) for i in np.array(data_list).T]

            #将17-17列表转换为0-0列表
            hour_data = [i for i in range(24)]
            for i in range(len(self.day_define)):
                hour_data[self.day_define[i]] = data_list[i]
        else:
            hour_data = [0 for i in range(24)]
        hour_data = list(np.array([i+1 for i in hour_rate])*np.array(hour_data))
        hour_data = [int(i) for i in hour_data]
        return hour_data
    #电量小时预测
    def electric_hour(self,strat_dict,data_ele):
        """
        计算电量小时列表
        :param:strat_dict:dict,策略字典
        :param data_ele: int,电量日预测值
        :return:hour_data：list,能量小时列表,shape =1*24
        """
        ##获取小时占比比率、策略模型预测字典、设备和工况表
        hour_rate = self.get_hour_rate() #各小时占比比率
        if len(strat_dict)>0:
            ld = load.Device_load()
            device = ld.load_device(self.graph_id)
            relation = ld.load_relation(self.graph_id)
            #计算策略各小时能量并转电量
            strat_list = []
            for key in strat_dict.keys():#对于策略字典中的每个工况
                conv_rate = device[device['device_id']==key[0]]["conversion_rate"].values[0]  #当前工况放能设备能效比
                loss_rate = relation[relation['device_from']==key[0]]["loss_rate"].values[0]  #当前工况放能设备损失率
                if device[device['device_id']==key[0]]["type_id"].values[0] == 1:
                    strat_list.append(np.array(strat_dict[key])/conv_rate/(1-loss_rate))
            strat_list = [sum(i) for i in np.array(strat_list).T]
            #将策略转电量17-17列表转换为0-0列表
            hour_strat = [i for i in range(24)]
            for i in range(len(self.day_define)):
                hour_strat[self.day_define[i]] = strat_list[i]
        else:
            hour_strat = [0 for i in range(24)]
        #计算电量减（能量转电量）后按比率分配到各小时0-0
        ele_minus_ene = data_ele-sum(hour_strat) if data_ele-sum(hour_strat)>=0 else 0
        hour_elec= [ele_minus_ene*i for i in hour_rate]
        #将能量转电量小时list与电量减（能量转电量）按比率分配小时list相加，得到电量小时列表
        hour_data = [hour_elec[i]+hour_strat[i] for i in range(len(hour_elec))]
        hour_data = [int(i) for i in hour_data]
        return hour_data
    #工况小时预测
    def strate_hour(self,strat_dict):
        """
        :param:strat_dict:dict,策略字典
        :return:dict_strate：dict,工况小时字典,key是工况code,value是list
        """
        ld = load.Device_load()
        dict_strate = {}
        if len(strat_dict)>0:
            device = ld.load_device(self.graph_id)
            for key in strat_dict.keys():
                dev_code = device[device["device_id"]==key[0]]["dev_code"].values[0]+"#"+device[device["device_id"]==key[1]]["dev_code"].values[0]
                #将策略转电量17-17列表转换为0-0列表
                hour_strat = [i for i in range(24)]
                for i in range(len(self.day_define)):
                    hour_strat[self.day_define[i]] = strat_dict[key][i]
                hour_strat = [int(k) for k in hour_strat]
                dict_strate[dev_code] = hour_strat
        return dict_strate
    #小时曲线转换为list匹配输出到数据库格式
    def hour_to_list(self,hour_list,date,dev_code):#将小时预测结果转换为输出到数据库的格式
        """
        输入24*1list转换为24*5二维列表,格式为输出到pre_data_hour格式,子列表元素分别代表[power,date,dev_code,graph_id,stgy_type]
        :param hour_list:
        :param date:
        :param dev_code:
        :return:
        """
        list_hour = []
        for i in range(len(hour_list)):
            item_time = datetime.datetime(date.year,date.month,date.day,i,0,0)
            item_list = [int(hour_list[i]),item_time,dev_code,int(self.graph_id),int(self.stgy_type)]
            list_hour.append(item_list)
        return list_hour
def main(strat_dict, data_ele):
    """
    预测能量、电量、策略小时结果并将结果合并为list
    :param data_ene:
    :param date:
    :param data_ele:
    :return:
    """
    ph = predict_hour(date)
    ene_hour = ph.energy_hour(strat_dict)
    ele_hour = ph.electric_hour(strat_dict, data_ele)
    strate_hour = ph.strate_hour(strat_dict)
    ld = load.Device_load()
    dev_code_ene = ld.load_station_info()['energy_code']
    dev_code_ele = ld.load_station_info()['battery_code']
    ene_list = ph.hour_to_list(ene_hour, date, dev_code_ene)
    ele_list = ph.hour_to_list(ele_hour, date,dev_code_ele)
    list_com = ene_list+ele_list
    for key in strate_hour.keys():
        strate_list = ph.hour_to_list(strate_hour[key], date,key)
        list_com.append(strate_list)

if __name__ =="__main__":
    """
    将电量、能量、策略日预测分散到各小时中
    """
    data_ene = 3000
    date = datetime.datetime.today()
    data_ele = 2000
    sm = sa.Strategic_model(int(data_ene),date)
    strat_matrix = sm.strate_model()
    strat_dict, strat_list = sm.strate_format(strat_matrix, date)  # 执行策略模型的主函数
    main(strat_dict, data_ele)




